package nl.dxn.tunnel.client;

import nl.dxn.tunnel.CollectionUtils;
import nl.dxn.tunnel.client.client.AgentClient;
import nl.dxn.tunnel.client.config.ProxyConfig;
import nl.dxn.tunnel.client.config.TcpConfigProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ClientApplication {

    private static final Logger logger = LoggerFactory.getLogger(ClientApplication.class);

    private ProxyConfig proxyConfig;

    private List<AgentClient> agentList = new ArrayList<>();

    public static ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);

    public ClientApplication()
    {
        Runtime.getRuntime().addShutdownHook(new Thread(this::destroy));

        ProtectionDomain protectionDomain = this.getClass().getProtectionDomain();
        CodeSource codeSource = protectionDomain.getCodeSource();
        URL location = codeSource.getLocation();
        File codeSourceFile = new File(location.getPath());
        File file = new File(codeSourceFile.getParent(),"/config/client.yml");
        logger.info("加载文件地址：{}",file.getPath());

        if(file.exists()) {
            try (FileInputStream fis = new FileInputStream(file);
                 InputStreamReader isr = new InputStreamReader(fis)) {
                this.proxyConfig = new Yaml().loadAs(isr, ProxyConfig.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else
        {
            InputStream resource = ClassLoader.getSystemResourceAsStream("client.yml");
            if (resource != null) {
                logger.info("加载文件地址：getSystemResourceAsStream client.yml");
                this.proxyConfig = new Yaml().loadAs(resource, ProxyConfig.class);
            }
        }
    }

    public void destroy() {
        try {
            for(AgentClient httpAgent:agentList){
                if(httpAgent != null)
                {
                    httpAgent.destroy();
                }
            }
        } catch (Exception ex) {

        }

        try {
            if (pool != null) {
                pool.shutdown();
            }
        } catch (Exception ex) {

        }
    }

    public void run(String... args) throws Exception {
        if (CollectionUtils.isEmpty(proxyConfig.getAgent())) {
            logger.info("未配置代理信息");
            System.exit(-1);
            return;
        }

        if(!CollectionUtils.isEmpty(proxyConfig.getAgent()))
        {
            for(TcpConfigProperties tcpConfigProperties:proxyConfig.getAgent())
            {
                AgentClient httpAgent = new AgentClient(proxyConfig.getTransferServerIp(),proxyConfig.getTransferServerPort(),tcpConfigProperties,proxyConfig.getAgentId(),proxyConfig.getAgentKey());
                boolean runResult = httpAgent.run();
                if (!runResult) {
                    logger.error(tcpConfigProperties.getServerId()+"启动失败");
                    System.exit(-1);
                    return;
                }

                agentList.add(httpAgent);
            }
        }
    }

    public void checkRun()
    {
        // 在1s后执行任务 之后每2s执行一次任务
        pool.scheduleAtFixedRate(() -> {
            for(AgentClient httpAgent:agentList){
                try {
                    if(httpAgent != null)
                    {
                        httpAgent.run();
                    }
                } catch (Exception e) {
                    logger.error("连接失败",e);
                }
            }

        }, 5, 5, TimeUnit.SECONDS);
    }
}
